]> dgit.raspbian.org Git - libreoffice.git/commitdiff
[PATCH] firebird: don't attach a database that is not in the normal backup state
authorCaolán McNamara <caolan.mcnamara@collabora.com>
Sun, 12 Jul 2026 16:09:48 +0000 (16:09 +0000)
committerRene Engelhard <rene@debian.org>
Sat, 3 Oct 2026 10:46:08 +0000 (12:46 +0200)
A database we extract from a .odb is always in the normal backup state,
so refuse one that is not, we're not interested in the difference file
mode case.

firebird upstream attempt as:
https://github.com/FirebirdSQL/firebird/pull/9089

And do it manually for the system-firebird case.

Change-Id: Iff9ebbb075379ca47a7f7f5886b693ac23860566
Signed-off-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Reviewed-on: https://gerrit.collaboraoffice.com/c/core/+/6702
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
(cherry picked from commit e7ea381e87cadaf31bf1ad2213a23f17a6284d1c)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208040
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Tested-by: Xisco Fauli <xiscofauli@libreoffice.org>
Signed-off-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208064
Tested-by: Jenkins
Signed-off-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208076
Signed-off-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208112
Tested-by: Christian Lohmaier <lohmaier+LibreOffice@googlemail.com>
Reviewed-by: Hossein <hossein@libreoffice.org>
Reviewed-by: Christian Lohmaier <lohmaier+LibreOffice@googlemail.com>
Gbp-Pq: Name CVE-2026-63266-3.diff

connectivity/source/drivers/firebird/Connection.cxx
external/firebird/UnpackedTarball_firebird.mk
external/firebird/firebird-nbak-difference-file-access.patch.1 [new file with mode: 0644]

index dad99cd50b8d81f1ed74f527e05d205c821b7852..c5e1e958af655ccfa33e925c983806f882e95cc5 100644 (file)
@@ -120,6 +120,39 @@ struct ConnectionGuard
     }
 };
 
+// A set nbackup state makes firebird open a difference file
+// (BackupManager::actualizeState and openDelta, firebird/src/jrd/nbak.cpp).
+// A database we made is never in that state, so refuse it.
+bool databaseHeaderHasBackupState(const OUString& rDatabasePath)
+{
+    OUString sFileURL;
+    if (::osl::FileBase::getFileURLFromSystemPath(rDatabasePath, sFileURL) != ::osl::FileBase::E_None)
+        return false;
+
+    ::osl::File aFile(sFileURL);
+    if (aFile.open(osl_File_OpenFlag_Read) != ::osl::FileBase::E_None)
+        return false;
+
+    // Ods::header_page, firebird/src/jrd/ods.h
+    sal_uInt8 aHeader[44];
+    sal_uInt64 nRead = 0;
+    ::osl::FileBase::RC eRead = aFile.read(aHeader, sizeof(aHeader), nRead);
+    aFile.close();
+
+    if (eRead != ::osl::FileBase::E_None || nRead < sizeof(aHeader))
+        return false;
+
+    // pag_type, Ods::pag_header
+    const sal_uInt8 nPageTypeHeader = 1;
+    if (aHeader[0] != nPageTypeHeader)
+        return false;
+
+    // hdr_flags & hdr_backup_mask, normal state is 0
+    const sal_uInt16 nFlags = aHeader[42] | (aHeader[43] << 8);
+    const sal_uInt16 nBackupStateMask = 0x0C00;
+    return (nFlags & nBackupStateMask) != 0;
+}
+
 }
 
 void Connection::construct(const OUString& url, const Sequence< PropertyValue >& info,
@@ -184,6 +217,15 @@ void Connection::construct(const OUString& url, const Sequence< PropertyValue >&
                     SAL_INFO("connectivity.firebird", "Found .fdb instead of .fbk");
                     bIsFdbStored = true;
                     loadDatabaseFile(our_sFDBLocation, m_sFirebirdURL);
+                    // Decline a database whose header asks firebird to use a
+                    // difference file
+                    if (databaseHeaderHasBackupState(m_sFirebirdURL))
+                    {
+                        ::connectivity::SharedResources aResources;
+                        const OUString sMessage = aResources.getResourceString(STR_COULD_NOT_LOAD_FILE).replaceFirst(
+                            "$filename$", m_sConnectionURL);
+                        ::dbtools::throwGenericSQLException(sMessage, *this);
+                    }
                 }
                 else
                 {
index 821b167650d5b3bdd108b5edb4282d8c0bda94e8..bd802c6f18bc5c3a19a7f6ef3f3e72c4de001989 100644 (file)
@@ -31,6 +31,7 @@ $(eval $(call gb_UnpackedTarball_update_autoconf_configs,firebird,\
 #   at <https://github.com/FirebirdSQL/firebird/pull/6948> "extern/cloop: Missing dependencies of
 #   compilations on output directories":
 $(eval $(call gb_UnpackedTarball_add_patches,firebird,\
+        external/firebird/firebird-nbak-difference-file-access.patch.1 \
         external/firebird/firebird.disable-ib-util-not-found.patch.1 \
                external/firebird/firebird-Engine12.patch \
                external/firebird/firebird-rpath.patch.0 \
diff --git a/external/firebird/firebird-nbak-difference-file-access.patch.1 b/external/firebird/firebird-nbak-difference-file-access.patch.1
new file mode 100644 (file)
index 0000000..256d805
--- /dev/null
@@ -0,0 +1,47 @@
+Verify difference file path against DatabaseAccess
+
+The difference file opened in openDelta and beginBackup was not verified
+against DatabaseAccess like the other database file paths.
+
+Submitted upstream as https://github.com/FirebirdSQL/firebird/pull/9089
+
+--- firebird/src/jrd/nbak.cpp
++++ firebird/src/jrd/nbak.cpp
+@@ -35,6 +35,7 @@
+ #include "lck.h"
+ #include "cch.h"
+ #include "lck_proto.h"
++#include "jrd_proto.h"
+ #include "pag_proto.h"
+ #include "err_proto.h"
+ #include "cch_proto.h"
+@@ -224,6 +225,14 @@
+ void BackupManager::openDelta(thread_db* tdbb)
+ {
+       fb_assert(!diff_file);
++
++      // Verify difference file path against DatabaseAccess entry of firebird.conf
++      if (!JRD_verify_database_access(diff_name))
++      {
++              ERR_post(Arg::Gds(isc_conf_access_denied) << Arg::Str("difference file") <<
++                                                                                                       Arg::Str(diff_name));
++      }
++
+       diff_file = PIO_open(tdbb, diff_name, diff_name);
+
+       if (database->dbb_flags & (DBB_force_write | DBB_no_fs_cache))
+@@ -283,6 +292,14 @@
+       {
+               // Create file
+               NBAK_TRACE(("Creating difference file %s", diff_name.c_str()));
++
++              // Verify difference file path against DatabaseAccess entry of firebird.conf
++              if (!JRD_verify_database_access(diff_name))
++              {
++                      ERR_post(Arg::Gds(isc_conf_access_denied) << Arg::Str("difference file") <<
++                                                                                                               Arg::Str(diff_name));
++              }
++
+               diff_file = PIO_create(tdbb, diff_name, true, false);
+       }
+       catch (const Firebird::Exception&)